/*
 * Colaborador.java
 *
 * Created on 19 de Maio de 2007, 17:04
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package pt.iscte.dcti.es.rhplus.utilizador;

import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import pt.iscte.dcti.es.rhplus.sistema.CodigoPostal;
import pt.iscte.dcti.es.rhplus.sistema.UtensiliosParaStrings;
import pt.iscte.dcti.es.rhplus.sistema.persistencia.AcessoBD;

/**
 * 
 * @author Gustavo Cabral
 * @author Helena Monteiro
 * @author Joao Catarino
 * @author Tiago Moreiras
 */
public abstract class Colaborador extends Pessoa {

	/** Creates a new instance of Colaborador */
	public Colaborador(final int id_pessoa, final String nome, final char sexo, final int bi, final Date data_de_nascimento, final int nif,
			final String email, final int telefone, final int telemovel, final String morada, final String grupo_sanguineo,
			final CodigoPostal codigo_postal, final String nib, final String nss, final Date data_admissao, final double vencimento,
			final Date validade_contrato, final String horario_trabalho, final int numero_de_colaborador, final int id_hospital) {

		super(id_pessoa, nome, sexo, bi, data_de_nascimento, nif, email, telefone, telemovel, morada, grupo_sanguineo, codigo_postal);

		this.nib = nib;
		this.nss = nss;
		this.data_admissao = data_admissao;
		this.vencimento = vencimento;
		this.validade_contrato = validade_contrato;
		this.horario_trabalho = horario_trabalho;
		this.numero_de_colaborador = numero_de_colaborador;
		this.id_hospital = id_hospital;
	}

	public int getNumeroDeColaborador() {
		return numero_de_colaborador;
	}

	public String getNib() {
		return nib;
	}

	public String getNss() {
		return nss;
	}

	public String getTipo() {
		return "colaborador";
	}

	public Date getDataAdmissao() {
		return data_admissao;
	}

	public double getVencimento() {
		return vencimento;
	}

	public Date getValidadeContrato() {
		return validade_contrato;
	}

	public String getHorarioTrabalho() {
		return horario_trabalho;
	}

	public int getIdHospital() {
		return id_hospital;
	}

	public static void insereMedico(final Hashtable<String, Object> dados_colaborador) throws SQLException, ClassNotFoundException,
			InstantiationException, IllegalAccessException {

		// Inserir na base de dados - Pessoa.
		Pessoa.insere(dados_colaborador);

		// Inserir na base de dados - Colaborador
		int ultimo_id_inserido = Pessoa.devolveUltimoIdentificadorDeInsercao();

		AcessoBD acesso_bd = new AcessoBD();
		acesso_bd.carregaDriverEAbreLigacao();
		String qryName = new String("inserir_medico");
		dados_colaborador.put("var_id_pessoa", new Integer(ultimo_id_inserido));
		acesso_bd.executaUpdate(qryName, dados_colaborador);
		acesso_bd.fechaLigacao();
	}

	public static void insereEnfermeiro(final Hashtable<String, Object> dados_colaborador) throws SQLException, ClassNotFoundException,
			InstantiationException, IllegalAccessException {

		// Inserir na base de dados - Pessoa.
		Pessoa.insere(dados_colaborador);

		// Inserir na base de dados - Colaborador
		int ultimo_id_inserido = Pessoa.devolveUltimoIdentificadorDeInsercao();

		AcessoBD acesso_bd = new AcessoBD();
		acesso_bd.carregaDriverEAbreLigacao();
		String qryName = new String("inserir_enfermeiro");
		dados_colaborador.put("var_id_pessoa", new Integer(ultimo_id_inserido));
		acesso_bd.executaUpdate(qryName, dados_colaborador);
		acesso_bd.fechaLigacao();
	}

	public static void insereAdministrativo(final Hashtable<String, Object> dados_colaborador) throws SQLException, ClassNotFoundException,
			InstantiationException, IllegalAccessException {

		// Inserir na base de dados - Pessoa.
		Pessoa.insere(dados_colaborador);

		// Inserir na base de dados - Colaborador
		int ultimo_id_inserido = Pessoa.devolveUltimoIdentificadorDeInsercao();

		AcessoBD acesso_bd = new AcessoBD();
		acesso_bd.carregaDriverEAbreLigacao();
		String qryName = new String("inserir_administrativo");
		dados_colaborador.put("var_id_pessoa", new Integer(ultimo_id_inserido));
		acesso_bd.executaUpdate(qryName, dados_colaborador);
		acesso_bd.fechaLigacao();
	}

	public static LinkedList<Colaborador> devolveTodos() throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {

		LinkedList<Colaborador> colaboradores = new LinkedList<Colaborador>();

		// Consulta a BD
		AcessoBD acesso_bd = new AcessoBD();
		acesso_bd.carregaDriverEAbreLigacao();
		String qryName = new String("devolver_todos_os_colaboradores");
		ResultSet result_set = acesso_bd.executaSelect(qryName, null);

		while (result_set.next()) {
			int id_codigo_postal = result_set.getInt("id_codigo_postal");

			// Cria o Membro do Agregado e os outros elementos necess�rios
			int id_pessoa = result_set.getInt("id_pessoa");
			int id_hospital = result_set.getInt("id_hospital");
			int numero_de_colaborador = result_set.getInt("numero_de_colaborador");
			String nome = result_set.getString("nome");
			char sexo = result_set.getString("sexo").charAt(0);
			int bi = result_set.getInt("bi");
			Date data_de_nascimento = result_set.getDate("data_de_nascimento");
			int nif = result_set.getInt("nif");
			String email = result_set.getString("email");
			int telefone = result_set.getInt("telefone");
			int telemovel = result_set.getInt("telemovel");
			String morada = result_set.getString("morada");
			String grupo_sanguineo = result_set.getString("grupo_sanguineo");
			String tipo = result_set.getString("tipo");
			String nib = result_set.getString("nib");
			String nss = result_set.getString("nss");
			Date data_admissao = result_set.getDate("data_admissao");
			Double vencimento = result_set.getDouble("vencimento");
			Date validade_contrato = result_set.getDate("validade_contrato");
			String horario_trabalho = result_set.getString("horario_trabalho");
			String especialidade = result_set.getString("especialidade");
			CodigoPostal codigo_postal = CodigoPostal.devolve(id_codigo_postal);

			if (tipo.equalsIgnoreCase(Colaborador.ADMINISTRATIVO))
				colaboradores.add(new Administrativo(id_pessoa, nome, sexo, bi, data_de_nascimento, nif, email, telefone, telemovel, morada,
						grupo_sanguineo, codigo_postal, nib, nss, data_admissao, vencimento, validade_contrato, horario_trabalho,
						numero_de_colaborador, id_hospital));
			else if (tipo.equalsIgnoreCase(Colaborador.MEDICO))
				colaboradores.add(new Medico(id_pessoa, nome, sexo, bi, data_de_nascimento, nif, email, telefone, telemovel, morada, grupo_sanguineo,
						codigo_postal, nib, nss, data_admissao, vencimento, validade_contrato, horario_trabalho, numero_de_colaborador,
						especialidade, id_hospital));
			else
				// Colaborador.ENFERMEIRO
				colaboradores.add(new Enfermeiro(id_pessoa, nome, sexo, bi, data_de_nascimento, nif, email, telefone, telemovel, morada,
						grupo_sanguineo, codigo_postal, nib, nss, data_admissao, vencimento, validade_contrato, horario_trabalho,
						numero_de_colaborador, id_hospital));
		}

		acesso_bd.fechaLigacao();

		return colaboradores;
	}

	public static void alteraMedico(final Hashtable<String, Object> dados_colaborador) throws SQLException, ClassNotFoundException,
			InstantiationException, IllegalAccessException {

		Utente.altera(dados_colaborador);

		AcessoBD acesso_bd = new AcessoBD();
		acesso_bd.carregaDriverEAbreLigacao();
		String qryName = new String("alterar_medico");
		acesso_bd.executaUpdate(qryName, dados_colaborador);
		acesso_bd.fechaLigacao();
	}

	public static void alteraEnfermeiro(final Hashtable<String, Object> dados_colaborador) throws SQLException, ClassNotFoundException,
			InstantiationException, IllegalAccessException {

		Utente.altera(dados_colaborador);

		AcessoBD acesso_bd = new AcessoBD();
		acesso_bd.carregaDriverEAbreLigacao();
		String qryName = new String("alterar_enfermeiro");
		acesso_bd.executaUpdate(qryName, dados_colaborador);
		acesso_bd.fechaLigacao();
	}

	public static void alteraAdministrativo(final Hashtable<String, Object> dados_colaborador) throws SQLException, ClassNotFoundException,
			InstantiationException, IllegalAccessException {

		Utente.altera(dados_colaborador);

		AcessoBD acesso_bd = new AcessoBD();
		acesso_bd.carregaDriverEAbreLigacao();
		String qryName = new String("alterar_administrativo");
		acesso_bd.executaUpdate(qryName, dados_colaborador);
		acesso_bd.fechaLigacao();

	}

	public static void remove(final int id_pessoa) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
		// Remove da base de dados - Pessoa.
		Pessoa.remove(id_pessoa);

		AcessoBD acesso_bd = new AcessoBD();
		acesso_bd.carregaDriverEAbreLigacao();
		String qryName = new String("remover_colaborador");
		Hashtable<String, Object> dados_da_pessoa = new Hashtable<String, Object>();
		dados_da_pessoa.put("var_id_pessoa", new Integer(id_pessoa));

		acesso_bd.executaUpdate(qryName, dados_da_pessoa);
		acesso_bd.fechaLigacao();

	}

	public static LinkedList devolveHorariosDeTrabalho() throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {

		// Consulta a BD
		AcessoBD acesso_bd = new AcessoBD();
		acesso_bd.carregaDriverEAbreLigacao();
		String qryName = new String("devolve_horarios_de_trabalho");
		ResultSet result_set = acesso_bd.executaSelect(qryName, null);
		result_set.next();

		String enum_horarios_de_trabalho = result_set.getString("type");
		LinkedList horarios_trabalho = Colaborador.converteHorarios(enum_horarios_de_trabalho);

		return horarios_trabalho;
	}

	public static LinkedList<String> converteHorarios(final String horarios) {
		LinkedList<String> lista_de_horarios = new LinkedList<String>();
		String regex = "\\d{1,2}:\\d{2}-\\d{1,2}:\\d{2}";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(horarios);
		while (matcher.find()) {
			int start = matcher.start();
			int end = matcher.end();
			lista_de_horarios.add(horarios.substring(start, end));
		}
		return lista_de_horarios;
	}

	public static LinkedList<String> converteEspecialidades(final String especialidades) {
		LinkedList<String> lista_de_especialidades = new LinkedList<String>();
		String regex = "\\d{1,2}:\\d{2}-\\d{1,2}:\\d{2}";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(especialidades);
		while (matcher.find()) {
			int start = matcher.start();
			int end = matcher.end();
			lista_de_especialidades.add(especialidades.substring(start, end));
		}
		return lista_de_especialidades;
	}

	public static LinkedList<String> devolveTodasAsEspecialidades() throws SQLException, ClassNotFoundException, InstantiationException,
			IllegalAccessException {

		// Consulta a BD
		AcessoBD acesso_bd = new AcessoBD();
		acesso_bd.carregaDriverEAbreLigacao();
		String qryName = new String("devolve_especialidades");
		ResultSet result_set = acesso_bd.executaSelect(qryName, null);
		result_set.next();

		String enum_especialidades = result_set.getString("type");

		LinkedList<String> especialidades = UtensiliosParaStrings.separaTipoEnumerado(enum_especialidades);

		return especialidades;
	}

	public Hashtable<String, Object> toHashtable() {
		Hashtable<String, Object> dados_pessoa = super.toHashtable();

		dados_pessoa.put("var_nib", new String(this.getNib()));
		dados_pessoa.put("var_nss", new String(this.getNss()));
		dados_pessoa.put("var_data_admissao", this.getDataAdmissao());
		dados_pessoa.put("var_vencimento", new Double(this.getVencimento()));
		dados_pessoa.put("var_validade_contrato", this.getValidadeContrato());
		dados_pessoa.put("var_hoprario_trabalho", this.getHorarioTrabalho());
		dados_pessoa.put("var_numero_de_colaborador", new Integer(this.getNumeroDeColaborador()));
		dados_pessoa.put("var_id_hospital", new Integer(this.getIdHospital()));

		return dados_pessoa;
	}

	@Override
	public String toString() {
		String colaborador_em_string = super.toString();

		return colaborador_em_string + ";" + numero_de_colaborador + ";" + nib + ";" + nss + ";" + data_admissao + ";" + vencimento + ";"
				+ validade_contrato + ";" + horario_trabalho + ";";
	}

	protected int numero_de_colaborador;
	private String nib;
	private String nss;
	private Date data_admissao;
	private double vencimento;
	private Date validade_contrato;
	private String horario_trabalho;
	final int id_hospital;

	public static final String MEDICO = "medico";
	public static final String ENFERMEIRO = "enfermeiro";
	public static final String ADMINISTRATIVO = "administrativo";

}
